#include "MyMqtt.h"
#include "Common.h"

/**
 * @brief 初始化函数
 * @return 
 */
bool MyMqtt::init()
{
    _mqtt->setClient(*_client);
    _mqtt->setServer(_server, _port);
    _mqtt->setCallback(_callback);
    LOG_F("[MyMqtt] init OK, SERVER:[%s] PORT:[%d]", _server, _port);
    return true;
}

/**
 * @brief 建立连接
 * @return 
 */
bool MyMqtt::connect()
{
    LOG("[MyMqtt] connect server");

    if (_mqtt->connect(_token)) {
        LOG_F("[MyMqtt] connect OK TOKEN:[%s]", _token);
        return true;
    }

    LOG("[MyMqtt] connect FAIL");
    return false;
}

/**
 * @brief 获取连接状态（需要周期执行）
 * @return 
 */
bool MyMqtt::getStatus()
{
    if (_mqtt->connected()) {
        _mqtt->loop();
        LOG("[MyMqtt] connect OK");
        return true;
    }

    LOG("[MyMqtt] connect FAIL");
    return false;
}

/**
 * @brief 订阅主题
 * @return 
 */
bool MyMqtt::subscribe()
{
    LOG("[MyMqtt] subscribe...");
    unsigned char subCount = 0;

    if (_mqtt->subscribe(_topic0)) {
        subCount++;
      LOG_F("[MyMqtt] subscribe OK TOPIC:[%s]", _topic0);
    }

    if (_mqtt->subscribe(_topic2)) {
        subCount++;
        LOG_F("[MyMqtt] subscribe OK TOPIC:[%s]", _topic2);
    }

    if (subCount != 2) {
        LOG("[MyMqtt] subscribe FAIL");
        return false;
    }
    
    return true;
}

/**
 * @brief 发布订阅
 * @param msg 
 * @return 
 */
bool MyMqtt::publish(const char *msg)
{
    LOG("[MyMqtt] publish...");
    unsigned char pubCount = 0;

    if (_mqtt->publish(_topic0, msg)) {
        pubCount++;
        LOG_F("[MyMqtt] publish OK TOPIC:[%s] MSG:[%s]", _topic0, msg);
    }

    if (_mqtt->publish(_topic2, msg)) {
        pubCount++;
        LOG_F("[MyMqtt] publish OK TOPIC:[%s] MSG:[%s]", _topic2, msg);
    }

    if (pubCount != 2) {
        LOG("[MyMqtt] publish FAIL");
        return false;
    }
    return true;
}

/**
 * @brief 构造函数
 * @param  
 */
MyMqtt::MyMqtt(void)
{
    _client = new WiFiClient();
    _mqtt = new PubSubClient();
    _state = MQTT_STATUS::INIT;
}

/**
 * @brief 析构函数
 * @param  
 */
MyMqtt::~MyMqtt(void)
{
    delete _client;
    delete _mqtt;
}

/**
 * @brief 状态机
 * @param  
 */
void MyMqtt::stateMachine(void)
{
    switch (_state)
    {
    case MQTT_STATUS::INIT:
        init();
        _state = MQTT_STATUS::CONNECT;
        break;

    case MQTT_STATUS::CONNECT:
        connect();
        _state = MQTT_STATUS::SUBSCRIBE;
        break;

    case MQTT_STATUS::SUBSCRIBE:
        subscribe();
        _state = MQTT_STATUS::RUNNING;
        break;
    
    case MQTT_STATUS::RUNNING:
        if (!getStatus()) {
            _state = MQTT_STATUS::CONNECT;
        }
        break;
    
    default:
        _state = MQTT_STATUS::INIT;
        break;
    }
}

/**
 * @brief 配置运行参数
 * @param server 
 * @param port 
 * @param token 
 * @param topic 
 * @param  
 */
void MyMqtt::configArg(const char *server, uint16_t port, const char *token, const char *topic0, const char* topic2, MQTT_CALLBACK_SIGNATURE)
{
    _server = server;
    _port = port;
    _token = token;
    _topic0 = topic0;
    _topic2 = topic2;
    _callback = callback;
}
